﻿using Furion.FriendlyException;
using GMS.NET.Const;
using GMS.NET.Core.Entitys.System;
using GMS.NET.Core.Users;
using GMS.NET.Dto.System.AccRoles.Enums;
using GMS.NET.Dto.System.AccRoles.Input;
using GMS.NET.Dto.System.AccRoles.Output;
using GMS.NET.Dto.System.AccRoles.Shared;
using GMS.NET.Dto.System.Menus.Enums;
using GMS.NET.SqlSugarCore.DbCore;
using Mapster;

namespace GMS.NET.Application.Service.System.Roles
{
    [Authorize]
    [DynamicApiController]
    public class AccRolesService : DbManger, IAccRolesService
    {
        public async Task<bool> CheckRoleNameRepeat([FromBody] string roleName)
        {
            var IsTobe = await MasterDb.Queryable<GMSNet_Role>()
                .AnyAsync(x => x.Role_Name == roleName);
            return IsTobe;
        }
        public async Task DelRolesData([FromBody] List<Guid> Ids)
        {
            var userAdmin = App.GetOptions<UserAdminOptions>();
            if (Ids.Any(x => x == new Guid(userAdmin.RoleId!)))
                throw Oops.Bah("不可删除管理员角色");
            await MasterDb.Deleteable<GMSNet_Role>()
                .Where(x => Ids.Contains(x.Id))
                .ExecuteCommandAsync();
        }
        [HttpPost]
        public async Task<TabularData<RolesData>> GetRolesData([FromBody] QueryPivot queryPivot)
        {
            RefAsync<int> total = 0;
            var result = await MasterDb.Queryable<GMSNet_Role>()
                .LeftJoin<GMSNet_Customer>((x, y) => x.Role_Custs == y.Id)
               .WhereIF(!UserInfo.UserAdmin, (x, y) => x.Role_Custs == Guid.Parse(UserInfo.CusId))
                .Where(queryPivot.WhereModel!.GetSearches())
                .Select((x, y) => new RolesData()
                {
                    Role_Custs = y.Id,
                    Id = x.Id,
                    Role_Status = (Role_Status)x.Role_Status,
                    Role_CustsName = y.Cust_Name,
                    Role_Name = x.Role_Name,
                    Role_Remark = x.Role_Remark
                })
                .ToPageListAsync(queryPivot.PageIndex, queryPivot.PageSize, total);
            return new TabularData<RolesData>() { Items = result, page_Total = total };
        }
        [HttpPost]
        public async Task<List<WaitRess>> GetWaitRess([FromBody] Guid RoleId)
        {
            List<WaitRess> WaitRess;
            if (UserInfo.UserAdmin)
            {
                var appUserAdmin = App.GetOptions<UserAdminOptions>();
                var IsAdminRole = RoleId == Guid.Parse(appUserAdmin.RoleId!);
                if (IsAdminRole)
                {
                    WaitRess = await MasterDb.Queryable<GMSNet_Resouce>()
                       .OrderBy(x=> x.Res_Sort, OrderByType.Asc)
                        .Select(x => new WaitRess
                        {
                            Id = x.Id,
                            IsChecked = true,
                            HasChildren = true,
                            IsDisabled = SqlFunc.IF(x.Res_Disabled == (int)Res_Disabled.disabled).Return(true).End(false),
                            Icon = x.Res_Icon,
                            Text = x.Res_Name,
                            ParentId = x.Res_ParentId
                        }).ToListAsync();
                }
                else
                {
                    WaitRess = await MasterDb.Queryable<GMSNet_Resouce>()
                        .LeftJoin<GMSNet_Authority>((x, y) => x.Id == y.Auth_ResId)
                        .OrderBy((x,y) => x.Res_Sort, OrderByType.Asc)
                         .Select((x,y) => new WaitRess
                         {
                             Id = x.Id,
                             IsChecked = SqlFunc.IF(!SqlFunc.IsNullOrEmpty(y.Auth_ResId.ToString())
                             && y.Auth_ResId!=Guid.Empty).Return(true).End(false),
                             HasChildren = true,
                             IsDisabled = SqlFunc.IF(x.Res_Disabled == (int)Res_Disabled.disabled).Return(true).End(false),
                             Icon = x.Res_Icon,
                             Text = x.Res_Name,
                             ParentId = x.Res_ParentId
                         }).ToListAsync();
                }
            }
            else
            {
                var nowRoleRes = MasterDb.Queryable<GMSNet_Authority>()
                       .Where(x => x.Auth_RoleId == RoleId)
                       .Select(x => new { x.Auth_ResId });

                WaitRess = await MasterDb.Queryable<GMSNet_Resouce>()
                                               .InnerJoin<GMSNet_Authority>((x, y) => x.Id == y.Auth_ResId)
                                               .Where((x, y) => y.Auth_RoleId == Guid.Parse(UserInfo.RoleId))
                                               .MergeTable()
                                               .LeftJoin(nowRoleRes, (x1, y1) => x1.Id == y1.Auth_ResId)
                                               .Where((x1, y1) => x1.Res_Disabled == (int)Res_Disabled.normal)
                                               .OrderBy((x1, y1) => x1.Res_Sort, OrderByType.Asc)
                                               .Select((x1, y1) => new WaitRess
                                               {
                                                   Id = x1.Id,
                                                   IsChecked = SqlFunc.IF(!SqlFunc.IsNullOrEmpty(y1.Auth_ResId.ToString())
                                                        && y1.Auth_ResId != Guid.Empty).Return(true).End(false),
                                                   HasChildren = true,
                                                   Icon = x1.Res_Icon,
                                                   Text = x1.Res_Name,
                                                   ParentId = x1.Res_ParentId
                                               }).ToListAsync();
            }
            return WaitRess;
        }
        [HttpPost]
        public async Task<TabularData<WaitUsers>> GetWaitUsers([FromBody] QueryPivot queryPivot)
        {
            var roleAdminId = App.GetOptions<UserAdminOptions>().RoleId;
            RefAsync<int> total = 0;
            var result = await MasterDb.Queryable<GMSNet_User>()
                .WhereIF(!UserInfo.UserAdmin, x => x.User_CusId == Guid.Parse(UserInfo.CusId)
                && x.User_RoleId != Guid.Parse(roleAdminId!))
                .Where(queryPivot.WhereModel!.GetSearches())
                .MergeTable()
                .LeftJoin<GMSNet_Customer>((x, y) => x.User_CusId == y.Id)
                .LeftJoin<GMSNet_Role>((x, y, z) => x.User_RoleId == z.Id)
                .Select((x, y, z) => new WaitUsers
                {
                    Id = x.Id,
                    User_Account = x.User_Account,
                    User_Name = x.User_Name,
                    Custs_Name = y.Cust_Name,
                    Role_Name = z.Role_Name
                })
                .ToPageListAsync(queryPivot.PageIndex, queryPivot.PageSize, total);
            return new TabularData<WaitUsers>() { Items = result, page_Total = total };
        }
        public async Task RoleStatus(int status, Guid Id)
        {
            var roleAdminId = App.GetOptions<UserAdminOptions>().RoleId;
            if (Id == Guid.Parse(UserInfo.RoleId))
                throw Oops.Bah("操作人不可修改操作人角色状态");
            if (Id == Guid.Parse(roleAdminId!))
                throw Oops.Bah("不可修改系统管理员角色状态");
            await MasterDb.Updateable<GMSNet_Role>()
                .SetColumns(x => x.Role_Status == status)
                .Where(x => x.Id == Id)
                .ExecuteCommandAsync();
        }
        public async Task SaveRolesData([FromBody] RolesData rolesData)
        {
            var roles = rolesData.Adapt<GMSNet_Role>();
            if (roles.Id != Guid.Empty)
            {
                await MasterDb.Updateable<GMSNet_Role>()
                    .Where(x => x.Id == roles.Id)
                    .SetColumns(x => x.Role_Name == roles.Role_Name)
                    .SetColumnsIF(roles.Role_Custs != Guid.Empty, x => x.Role_Custs == roles.Role_Custs)
                    .SetColumns(x => x.Role_Remark == roles.Role_Remark)
                    .SetColumns(x => x.Role_Status == roles.Role_Status)
                    .CallEntityMethod(it => it.SetUpdateUser())
                    .ExecuteCommandAsync();
            }
            else
            {
                if (!UserInfo.UserAdmin) roles.Role_Custs = Guid.Parse(UserInfo.CusId);
                await MasterDb.Insertable(roles)
                    .CallEntityMethod(it => it.SetAddUser())
                    .ExecuteCommandAsync();
            }
        }
        public async Task SetAccRess([FromBody] AccRess acc)
        {
            if (acc.Role == Guid.Parse(UserInfo.RoleId))
                throw Oops.Bah("不可修改系统管理员权限");
            if (acc.Role == Guid.Parse(UserInfo.RoleId))
                throw Oops.Bah("操作人不可分配操作人权限");

            var authList = new List<GMSNet_Authority>();
            acc.Ress!.ForEach(x =>
            {
                authList.Add(new()
                {
                    Auth_ResId = x,
                    Auth_RoleId = acc.Role
                });
            });

                MasterDb.Deleteable<GMSNet_Authority>()
                .Where(x => x.Auth_RoleId == acc.Role)
                .ExecuteCommand();

            await MasterDb.Insertable(authList)
                .CallEntityMethod(it => it.SetAddUser())
                .ExecuteCommandAsync();
        }
        public async Task SetAccUsers([FromBody] AccUsers acc)
        {
            await MasterDb.Updateable<GMSNet_User>()
                .SetColumns(x => x.User_RoleId == acc.Role)
                .Where(x => acc.Users!.Contains(x.Id))
                .ExecuteCommandAsync();
        }
    }
}
